package cn.coisini.utils;

import java.util.concurrent.atomic.AtomicReference;

/**
 * @author xiangshaw
 * Description: ThreadLocal 工具类（线程本地变量）
 * 使用了 AtomicReference<ThreadLocal<String>> 类型来表示 USER_LOCAL 字段，确保对其引用的更新是线程安全的。
 * 然后，在需要延迟初始化 ThreadLocal 实例时，使用了双重检查锁定，并在内部使用 compareAndSet 方法来确保线程安全的更新
 */
public class ThreadLocalUtil {
    // 添加私有构造函数
    private ThreadLocalUtil() {
        // 防止该类被实例化
        throw new AssertionError("Utility class should not be instantiated");
    }

    // 延迟初始化 ThreadLocal 实例
    private static final AtomicReference<ThreadLocal<String>> USER_LOCAL = new AtomicReference<>();

    // 获取值
    public static String get() {
        return getUserLocal().get();

    }

    // 赋值
    public static void set(String value) {
        getUserLocal().set(value);
    }

    // 移除
    public static void remove() {
        getUserLocal().remove();
    }

    // 懒加载，获取 ThreadLocal 实例
    private static ThreadLocal<String> getUserLocal() {
        if (USER_LOCAL.get() == null) {
            synchronized (ThreadLocalUtil.class) {
                if (USER_LOCAL.get() == null) {
                    USER_LOCAL.set(new ThreadLocal<>());
                }
            }
        }
        return USER_LOCAL.get();
    }

    // 判断 ThreadLocal 是否有值
    public static boolean present() {
        return getUserLocal().get() != null;
    }

    // 获取 ThreadLocal 的值，如果没有值则返回默认值
    public static String getOrDefault(String defaultValue) {
        return present() ? getUserLocal().get() : defaultValue;
    }
}

